package org.fizz.ass;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.Charset;

import org.fizz.ass.html.AssHTMLDocument;

/**
 * 解析类
 * @author FIZZ
 * @version ass-1.0, 2014-4-17
 * @since 1.0
 */
public class AssParser {

	public static AssParser parser;
	
	private AssParser(){
	}
	
	public static AssParser getInstance(){
		if(parser == null){
			parser = new AssParser();
		}
		return parser;
	}
	

	public AssHTMLDocument parse(InputStream in, String encoding){
		InputStreamReader isr = null;
		BufferedReader br = null;
		try {
			isr = new InputStreamReader(in, encoding);
			br = new BufferedReader(isr);
			
			AssParserCallback parserCallback = new AssParserCallback();
			
//			ParserDelegator parserDelegator = new ParserDelegator();
//			parserDelegator.parse(isr, assPC, true);//传人流、解析HTML的回调类、忽略大小写
			
			AssParserDelegator parserDelegator = new AssParserDelegator();
			parserDelegator.parse(br, parserCallback);
			
			return parserCallback.getAssHTMLDocument();
//			return null;
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}finally{
			if(br != null){try {br.close();} catch (IOException e) {}}
			if(isr != null){try {isr.close();} catch (IOException e) {}}
			if(in != null){try {in.close();} catch (IOException e) {}}
		}
//		StringBuilder htmlStr = readHTML(in, encoding);
//		
//		System.out.println(htmlStr);
//		System.out.println(htmlStr.length());
//		System.out.println(htmlStr.toString().getBytes().length/1024);
//		return null;
	}
	
	/**
	 * 返回整个HTML文档的字符
	 * @param in HTML输入流
	 * @param encoding 字符编码
	 * @return 整个HTML文档的字符
	 * @since 1.0
	 */
	public String readHTML(InputStream in, String encoding){
		ReadableByteChannel rbc = null;
		try {
			rbc = Channels.newChannel(in);
			ByteBuffer buffer = ByteBuffer.allocate(1024);//分配一个1024的缓存
			
			Charset charset = Charset.forName(encoding);//字符集
			CharBuffer charBuffer = null;
			
			StringBuilder htmlStr = new StringBuilder();
			while(true){
				buffer.clear();
				int k = rbc.read(buffer);
				if(k == -1){
					break;
				}
				buffer.flip();
				charBuffer = charset.decode(buffer);
				htmlStr.append(charBuffer);
			}
			return htmlStr.toString();
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}finally{
			if(rbc != null){try {rbc.close();} catch (IOException e) {}}
		}
	}
	
}
